#ifndef cSingleton_H
#define  cSingleton_H


//--------------------------------------------------------------------------------------
// 

namespace Core
{
template <typename T>
class cSingleton
{
protected:
	cSingleton() {}
	virtual ~cSingleton() {}
private:
	cSingleton(cSingleton& s);
	const cSingleton& operator=(const cSingleton& s);
public:
	static T& Instance();
};

template <typename T>
T& cSingleton<T>::Instance()
{
	static T onlyInstance;
	return onlyInstance;
}

#define FRIENDSINGLETON(subClass) \
	friend class cSingleton<subClass>;

//=========================================
template <typename T>
class cSingletonHeap
{
protected:
	cSingletonHeap() {}
	virtual ~cSingletonHeap() {}
private:
	cSingletonHeap(cSingletonHeap& s);
	const cSingletonHeap& operator=(const cSingletonHeap& s);
protected:
	static T* m_pSingleton;
public:
	static T* InstancePtr();
	static T& InstanceRef();
	static void Destroy();
};

template <typename T>
T* cSingletonHeap<T>::m_pSingleton = 0;

template <typename T>
T* cSingletonHeap<T>::InstancePtr()
{
	if (m_pSingleton == 0)
		m_pSingleton = new T();

	return m_pSingleton;
}

template <typename T>
T& cSingletonHeap<T>::InstanceRef()
{
	return *InstancePtr();
}

template <typename T>
void cSingletonHeap<T>::Destroy()
{
	if (m_pSingleton != 0)
	{
		delete m_pSingleton;
		m_pSingleton = 0;
	}
}

#define FRIENDSINGLETONHEAP(subclass) \
	friend class cSingletonHeap<subclass>;

}	// endof namespace Core

#endif